package com.dragon.logical.service.customer.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dragon.common.model.ResultCode;
import com.dragon.common.model.exception.CustomException;
import com.dragon.common.util.DateNumUtils;
import com.dragon.logical.service.customer.CustomerService;
import com.dragon.logical.service.customer.QuotesService;
import com.dragon.repository.entity.AddPageData;
import com.dragon.repository.entity.Contract;
import com.dragon.repository.entity.Quotes;
import com.dragon.repository.entity.QuotesProducts;
import com.dragon.repository.mapper.*;
import com.qiniu.util.Md5;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 报价表 服务实现类
 * </p>
 *
 * @author sy
 * @since 2023-06-20
 */
@Service
public class QuotesServiceImpl extends ServiceImpl<QuotesMapper, Quotes> implements QuotesService {

    @Autowired
    QuotesMapper mapper;
    @Autowired
    AdminDepartmentMapper adMapper;
    @Autowired
    CustomerMapper customerMapper;
    @Autowired
    QuotesProductsMapper quotesProductsMapper;
    @Autowired
    VendorProductsMapper vendorProductsMapper;
    @Autowired
    ContractMapper contractMapper;
    @Autowired
    QuotesService quotesService;
    @Autowired
    CustomerService customerService;

    @Override
    public Page<Quotes> quotesList(Integer page, Integer limit, String search, Integer status, Integer recodeId,Integer isContract) {
        Page<Quotes> quotesPage = new Page<>(page, limit);
        return mapper.selectQuotes(quotesPage, search, status, recodeId,isContract);
    }

    @Override
    public Page<Quotes> quotesListByContractId(Integer page, Integer limit, String search, Integer status, Integer recodeId, Integer isContract) {
        Page<Quotes> quotesPage = new Page<>(page, limit);
        return mapper.selectQuotesList(quotesPage, search, status, recodeId,isContract);
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public AddPageData addQuotes(Quotes quotes) {
        Quotes quo = mapper.selectById(quotes.getId());
        if (quo != null) {
            throw new CustomException(ResultCode.DATA_ALREADY_EXISTS);
        }
        quotes.setStatus(0);
        quotes.setCreateTime(DateUtil.date());
        if (quotes.getDiscountMoney() == null){
            quotes.setDiscountMoney(0.00);
        }
        //自动生成编号
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String code = "BJ-" + sdf.format(quotes.getCreateTime());
        String maxCode =  mapper.maxRoundInoutNumber(code);
        String newCode = null;
        if (StrUtil.isEmpty(maxCode)){
            newCode = code + "001";
        }
        else {
            String getMaxCode = maxCode.substring(11, 14);
            newCode = code + DateNumUtils.getNum(getMaxCode);
        }
        quotes.setQuotesNumber(newCode);
        if (quotes.getDiscountMoney() != null){
            if (quotes.getPrice() < quotes.getDiscountMoney()){
                throw new CustomException(ResultCode.QUOTES_DISCOUNTMONEY_IS_NOT_BIG_TOTELMONEY);
            }
        }
        mapper.insert(quotes);
        List<QuotesProducts> quotesProductsIg = new ArrayList<>();
        quotes.getProducts().forEach(quotesProducts -> {
            Double price = quotes.getProducts().stream().
                    filter(e -> e.getProductsId().equals(quotesProducts.getProductsId()) && e.getOnePrice().equals(quotesProducts.getOnePrice()))
                    .map(QuotesProducts::getPrice).reduce((a, b) -> (a + b)).get();
            Long numbers = quotesProductsIg.stream().filter(e -> e.getProductsId().equals(quotesProducts.getProductsId()) && e.getOnePrice().equals(quotesProducts.getOnePrice())).count();
            if (numbers == 0) {
                if (!quotesProducts.getPrice().equals(price)) {
                    // 获取总共相同的数量
                    Integer nums = quotes.getProducts().stream().
                            filter(e -> e.getProductsId().equals(quotesProducts.getProductsId()) && e.getOnePrice().equals(quotesProducts.getOnePrice()))
                            .map(QuotesProducts::getNum).reduce((a, b) -> (a + b)).get();
                    quotesProductsIg.add(quotesProducts);
                    quotesProducts.setNum(nums);
                    quotesProducts.setPrice(price);
                }
                quotesProducts.setQuotesId(quotes.getId());
                quotesProductsMapper.insert(quotesProducts);
            }
        });


        AddPageData addPageData = new AddPageData();
        addPageData.setAdminId(quotes.getRecodeId());
        addPageData.setCorrelationId(quotes.getId());
        addPageData.setWorkflowJson(quotes.getWorkflowJsonList());
        addPageData.setStreamType(1);
        addPageData.setTitle(quotes.getQuotesName());
        addPageData.setExempt(quotes.getExempt());
        return addPageData;
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void updateQuotes(Quotes quotes) {
        Quotes quo = mapper.selectById(quotes.getId());
        if (quo == null) {
            throw new CustomException(ResultCode.QUOTES_DATA_NOT_FOUND);
        }
        if (quotes.getProducts() != null) {
            quotesProductsMapper.delete(new QueryWrapper<QuotesProducts>().lambda().eq(QuotesProducts::getQuotesId, quotes.getId()));
            List<QuotesProducts> quotesProductsIg = new ArrayList<>();
            quotes.getProducts().forEach(quotesProducts -> {
                Double price = quotes.getProducts().stream().
                        filter(e -> e.getProductsId().equals(quotesProducts.getProductsId()) && e.getOnePrice().equals(quotesProducts.getOnePrice()))
                        .map(QuotesProducts::getPrice).reduce((a, b) -> (a + b)).get();
                Long numbers = quotesProductsIg.stream().filter(e -> e.getProductsId().equals(quotesProducts.getProductsId()) && e.getOnePrice().equals(quotesProducts.getOnePrice())).count();
                if (numbers == 0) {
                    if (!quotesProducts.getPrice().equals(price)) {
                        // 获取总共相同的数量
                        Integer nums = quotes.getProducts().stream().
                                filter(e -> e.getProductsId().equals(quotesProducts.getProductsId()) && e.getOnePrice().equals(quotesProducts.getOnePrice()))
                                .map(QuotesProducts::getNum).reduce((a, b) -> (a + b)).get();
                        quotesProductsIg.add(quotesProducts);
                        quotesProducts.setNum(nums);
                        quotesProducts.setPrice(price);
                    }
                    quotesProducts.setQuotesId(quotes.getId());
                    quotesProductsMapper.insert(quotesProducts);
                }
            });
        }
        mapper.updateById(quotes);
    }

    @Override
    public void deleteQuotes(Integer id) {
        Quotes quotes = mapper.selectById(id);
        if (quotes == null) {
            throw new CustomException(ResultCode.QUOTES_DATA_NOT_FOUND);
        }
        QueryWrapper<Contract> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(Contract::getQuotesId, id).eq(Contract::getDeleted,0);
        if (contractMapper.selectOne(wrapper) == null) {
            //quotesProductsMapper.delete(new QueryWrapper<QuotesProducts>().lambda().eq(QuotesProducts::getQuotesId, id));
            quotes.setDeleted(1);
            mapper.updateById(quotes);
            customerService.deleteThorough(1,id);
        } else {
            throw new CustomException(ResultCode.QUOTES_IS_RELEVANCY_CONTRACT);
        }
    }

    @Override
    public Quotes selectDetailById(Integer id) {
        Quotes quotes = mapper.selectQuotesById(id);
        if (quotes == null) {
            throw new CustomException(ResultCode.QUOTES_DATA_NOT_FOUND);
        }
        List<QuotesProducts> quotesProducts = quotesProductsMapper.selectProductsList(id);
        quotesProducts.forEach(e -> {
            e.setProductsData(JSONObject.parseObject(JSONObject.toJSONString(e), QuotesProducts.class));
        });
        quotes.setProducts(quotesProducts);
        return quotes;
    }

    @Override
    public List<Quotes> selectByCustomerId(Integer id) {
        return mapper.selectList(new QueryWrapper<Quotes>().lambda().eq(Quotes::getCustomerId, id));
    }


    @Override
    public void exportExcel( HttpServletResponse response) {
        List<Quotes> list = quotesService.list();
        try {
            download(response,Quotes.class,list);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static void download(HttpServletResponse response, Class t, List list) throws IOException, IllegalAccessException, InstantiationException {
        response.setContentType("application/vnd.ms-excel");// 设置文本内省
        response.setCharacterEncoding("utf-8");// 设置字符编码
        response.setHeader("Content-disposition", "attachment;filename=demo.xlsx"); // 设置响应头
        EasyExcel.write(response.getOutputStream(), t).sheet("模板").doWrite(list); //用io流来写入数据
    }


    @Override
    public void antiAudit(Integer correlationId){
        //先存历史记录
        Quotes quotes = mapper.selectById(correlationId);
        QueryWrapper<Contract> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(Contract::getQuotesId,correlationId).eq(Contract::getStatus,1);
        List<Contract> contracts = contractMapper.selectList(wrapper);
        if (contracts.size() >0){
            throw new CustomException(ResultCode.QUOTES_IS_RELEVANCY_CONTRACT);
        } else {
            wrapper.clear();
            wrapper.lambda()
                    .eq(Contract::getQuotesId, correlationId)
                    .ne(Contract::getStatus,1);
            Contract contract = new Contract();
            contract.setDeleted(1);
            contract.setUpdateTime(DateUtil.date());
            contractMapper.update(contract,wrapper);
            quotes.setStatus(0);
            quotes.setIsContract(0);
            mapper.updateById(quotes);
        }
    }

}
